package com.ruoyi.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.app.dto.ScanInsideDto;
import com.ruoyi.dto.PaymentDto;
import com.ruoyi.app.dto.PaymentParkCardDto;
import com.ruoyi.app.mapper.AppMapper;
import com.ruoyi.app.service.IAppService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.domain.ParkingCardOrder;
import com.ruoyi.domain.ParkingInfo;
import com.ruoyi.domain.ParkingOrder;
import com.ruoyi.dto.PaymentInsideDto;
import com.ruoyi.forest.WeChatClient;
import com.ruoyi.framework.config.SmartParkingCloudConfig;
import com.ruoyi.mapper.*;
import com.ruoyi.merchant.domain.MerchantCouponIssue;
import com.ruoyi.merchant.domain.MerchantUsageRecord;
import com.ruoyi.merchant.mapper.MerchantCouponIssueMapper;
import com.ruoyi.merchant.mapper.MerchantCouponOrderMapper;
import com.ruoyi.merchant.mapper.MerchantUsageRecordMapper;
import com.ruoyi.service.IParkingInfoService;
import com.ruoyi.service.IWeChatService;
import com.ruoyi.vo.ScanInOutCodeVo;
import com.ruoyi.wss.WebSocketMessageService;
import com.ruoyi.wss.dahua.Enum.MasWebsocketEnum;
import com.ruoyi.wss.dahua.config.DaHuaConfig;
import com.ruoyi.wss.dahua.request.*;
import com.ruoyi.wss.dahua.response.ScanInOutCodeResponse;
import com.ruoyi.wss.dahua.response.ScanOnSiteCodeResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * App端Service业务层处理
 * 
 * @author dongdong
 * @date 2025-08-20
 */
@Slf4j
@Service
public class AppServiceImpl implements IAppService {

    @Autowired
    private WebSocketMessageService webSocketMessageService;
    @Autowired
    private IWeChatService weChatService;
    @Autowired
    private IParkingInfoService parkingInfoService;
    @Resource
    private WeChatClient weChatClient;
    @Resource
    private ParkingOrderMapper parkingOrderMapper;
    @Resource
    private ParkingInfoMapper parkingInfoMapper;
    @Resource
    private ParkingCardSpecMapper parkingCardSpecMapper;
    @Resource
    private ParkingCardMapper parkingCardMapper;
    @Resource
    private ParkingCardOrderMapper parkingCardOrderMapper;
    @Resource
    private MerchantCouponIssueMapper merchantCouponIssueMapper;
    @Resource
    private MerchantUsageRecordMapper merchantUsageRecordMapper;
    @Resource
    private MerchantCouponOrderMapper merchantCouponOrderMapper;


    @Override
    public String getOpenidByCode(String code) {
        Map<String, Object> map = weChatClient.getWxPublicOpenid(SmartParkingCloudConfig.APPID, SmartParkingCloudConfig.SECRET, code);
        Optional.ofNullable(map.get("openid")).orElseThrow(() -> new RuntimeException("未获取到openid，请重试"));
        return map.get("openid").toString();
    }

    @Override
    public String getXcxOpenidByCode(String code) {
        Map<String, Object> map = weChatClient.getWxXcxOpenid(SmartParkingCloudConfig.APPID_XCX, SmartParkingCloudConfig.SECRET_XCX, code);
        Optional.ofNullable(map.get("openid")).orElseThrow(() -> new RuntimeException("未获取到openid，请重试"));
        return map.get("openid").toString();
    }

    @Override
    public ScanInOutCodeVo scanInOutCode(ScanInOutCodeRequest scanInOutCodeRequest) {
        // 查询停车信息
        return createParkingOrder(null, scanInOutCodeRequest);
    }

    @Override
    public ScanInOutCodeVo scanInOutCodeV1(ScanInOutCodeRequest scanInOutCodeRequest) {
        String[] scene = scanInOutCodeRequest.getScene().split("-");
        if (scene.length != 2){
            return null;
        }
        ParkingInfo parkingInfo = parkingInfoMapper.selectParkingInfoById(Long.parseLong(scene[0]));
        if (Objects.isNull(parkingInfo)){
            return null;
        }
        scanInOutCodeRequest.setPlatformId(parkingInfo.getPlatformId());
        scanInOutCodeRequest.setQrId(scene[1]);
        ScanInOutCodeVo vo = createParkingOrder(parkingInfo, scanInOutCodeRequest);
        if (Objects.isNull(vo)){
            return null;
        }
        vo.setContactPhone(parkingInfo.getContactPhone());
        vo.setChargeDetail(parkingInfo.getChargeDetail());
        vo.setFirstTitle(parkingInfo.getFirstTitle());
        vo.setSecondTitle(parkingInfo.getSecondTitle());
        return vo;
    }

    public ScanInOutCodeVo createParkingOrder(ParkingInfo parkingInfo, ScanInOutCodeRequest scanInOutCodeRequest){
        String platformId = scanInOutCodeRequest.getPlatformId();
        // 组装请求
        RequestData<ScanInOutCodeRequest> requestData = new RequestData<>(
                MasWebsocketEnum.SCAN_IN_OUT_CODE.getMethod(), scanInOutCodeRequest);
        CommonRequest<ScanInOutCodeRequest> scanRequest = new CommonRequest<>("transform", 1, requestData);
        log.info("出入口扫码请求JSON：{}", scanInOutCodeRequest);
        try {
            ScanInOutCodeResponse scanInOutCodeResponse = webSocketMessageService.queryDevice(platformId, scanRequest, ScanInOutCodeResponse.class);
            log.info("出入口扫码查询的停车信息: {}", scanInOutCodeResponse);
            // 有效的停车缴费信息，生成平台订单（订单是否有效，暂时通过车牌号长度小于9判断）
            if(scanInOutCodeResponse.getCarNum().length() < 9){
                LocalDateTime entryTime = DateUtils.strToLocalDateTime(scanInOutCodeResponse.getCarInTime());
                LocalDateTime exitTime = DateUtils.strToLocalDateTime(scanInOutCodeResponse.getCarOutTime());
                ParkingOrder parkingOrder = new ParkingOrder();
                parkingOrder.setPlatformId(platformId);
                parkingOrder.setCarNum(scanInOutCodeResponse.getCarNum());
                parkingOrder.setEntryTime(entryTime);
                parkingOrder.setExitTime(exitTime);
                ParkingOrder order = parkingOrderMapper.selectParkingOrder(parkingOrder);
                if(Objects.isNull(order)){
                    if (Objects.isNull(parkingInfo)){
                        parkingInfo = parkingInfoMapper.selectParkingInfoByParkCode(platformId, scanInOutCodeResponse.getParkingLotCode());
                    }
                    Long parkId = parkingInfo.getId();
                    String orderNo = StringUtils.getOrderNo("ORD");
                    order = new ParkingOrder();
                    order.setOrderNo(orderNo);
                    order.setOrderStatus(1);
                    order.setOrderType(scanInOutCodeResponse.getAutoPass());
                    order.setPlatformId(platformId);
                    order.setParkId(parkId);
                    order.setParkCode(scanInOutCodeResponse.getParkingLotCode());
                    order.setParkName(scanInOutCodeResponse.getParkingLot());
                    order.setCarNum(scanInOutCodeResponse.getCarNum());
                    order.setEntryTime(entryTime);
                    order.setExitTime(exitTime);
                    // 计费时长（分钟）
                    Long totalMinutes = scanInOutCodeResponse.getParkTime();
                    Long freeMinutes = scanInOutCodeResponse.getFeeOutTime().longValue();
                    Long chargeMinutes = totalMinutes.longValue() - freeMinutes.longValue();
                    order.setTotalMinutes(totalMinutes);
                    order.setFreeMinutes(freeMinutes);
                    order.setChargeMinutes(chargeMinutes>0?chargeMinutes:0);
                    BigDecimal totalAmount = scanInOutCodeResponse.getConsumeMoney();
                    order.setTotalAmount(totalAmount);
                    // 查询用户是否有优惠券
                    MerchantCouponIssue couponIssue = merchantCouponIssueMapper.selectMerchantCouponIssueByCarNum(scanInOutCodeResponse.getCarNum(), parkId);
                    if(Objects.nonNull(couponIssue)){
                        order.setIssueId(couponIssue.getId());
                        BigDecimal discountAmount = couponIssue.getFaceValue();
                        BigDecimal actualAmount = totalAmount.subtract(discountAmount);
                        if (actualAmount.compareTo(BigDecimal.ZERO) >= 0){
                            order.setDiscountAmount(discountAmount);
                            order.setActualAmount(actualAmount);
                        }else {
                            order.setDiscountAmount(totalAmount);
                            order.setActualAmount(BigDecimal.ZERO);
                        }
                    }else {
                        order.setDiscountAmount(scanInOutCodeResponse.getPayedMoney());
                        order.setActualAmount(totalAmount.subtract(scanInOutCodeResponse.getPayedMoney()));
                    }
                    order.setExitGateId(scanInOutCodeResponse.getParkingLotCode());
                    order.setExitGateName(scanInOutCodeResponse.getParkingLot());
                    order.setCreateTime(new Date());
                    order.setDeptId(parkingInfo.getDeptId());
                    parkingOrderMapper.insertParkingOrder(order);
                }
                ScanInOutCodeVo vo = BeanUtil.copyProperties(order, ScanInOutCodeVo.class);
                return vo;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("出入口扫码查询的停车信息异常: {}", e.getMessage());
        }
        return null;
    }

    @Override
    @Transactional
    public Map<String, String> payment(PaymentDto paymentDto) {
        ParkingOrder parkingOrder = new ParkingOrder();
        parkingOrder.setOrderNo(paymentDto.getOrderNo());
        ParkingOrder order = parkingOrderMapper.selectParkingOrder(parkingOrder);
        Optional.ofNullable(order).orElseThrow(() -> new RuntimeException("暂未查询到缴费的订单"));
        parkingOrderMapper.updateOrderStatusById(2, order.getId());
        paymentDto.setBody(order.getParkName()+"-"+order.getCarNum());
        paymentDto.setAmount(order.getActualAmount());
        return weChatService.weChatPay(paymentDto);
    }
    /**
     * 场内扫码订单支付
     * @param paymentInsideDto
     * @return
     */
    @Override
    @Transactional
    public Map<String, String> paymentInside(PaymentInsideDto paymentInsideDto) {
//        log.info("场内扫码订单支付参数:{}",paymentInsideDto);
        ParkingInfo parkingInfo = parkingInfoService.selectParkingInfoById(paymentInsideDto.getParkId());
        if (parkingInfo == null){
            throw new RuntimeException("未查询到停车场信息");
        }
        ScanInOutCodeVo inParkingFeeInfo = getInParkingFeeInfo(parkingInfo, paymentInsideDto.getCarNum());
        if(inParkingFeeInfo == null){
            throw new RuntimeException("未查询到入场信息");
        }
        ParkingOrder queryParms = new ParkingOrder();
        queryParms.setCarNum(paymentInsideDto.getCarNum());
        queryParms.setUniqueId(paymentInsideDto.getUniqueId());
        queryParms.setParkId(paymentInsideDto.getParkId());
        queryParms.setOrderStatus(2);
        ParkingOrder order = parkingOrderMapper.selectParkingOrder(queryParms);
        //查询出这个人和车的待支付订单，如果不存在，则创建，如果存在，则更新
        if(order == null){
            order = new ParkingOrder();
        }

        Long parkId = parkingInfo.getId();
        String orderNo = StringUtils.getOrderNo("ORD");
        order.setUniqueId(paymentInsideDto.getUniqueId());
        order.setOrderNo(orderNo);
        order.setOrderStatus(2);
        //订单类型：场内缴费
        order.setOrderType(3);
        order.setPlatformId(parkingInfo.getPlatformId());
        order.setParkId(parkId);
        order.setParkCode(parkingInfo.getParkCode());
        order.setParkName(parkingInfo.getParkName());
        order.setCarNum(paymentInsideDto.getCarNum());
        order.setEntryTime(inParkingFeeInfo.getEntryTime());
        order.setExitTime(LocalDateTime.now());
        // 计费时长（分钟）
        Long totalMinutes = inParkingFeeInfo.getChargeMinutes();
        Long freeMinutes = inParkingFeeInfo.getFreeMinutes().longValue();
        Long chargeMinutes = totalMinutes.longValue() - freeMinutes.longValue();
        order.setTotalMinutes(totalMinutes);
        order.setFreeMinutes(freeMinutes);
        order.setChargeMinutes(chargeMinutes>0?chargeMinutes:0);
        BigDecimal totalAmount = inParkingFeeInfo.getTotalAmount();
        order.setTotalAmount(totalAmount);
        order.setDiscountAmount(inParkingFeeInfo.getDiscountAmount());
        order.setActualAmount(inParkingFeeInfo.getActualAmount());
        order.setDeptId(parkingInfo.getDeptId());
        log.info("场内扫码创建订单成功: {}", order);

        // 判断是新增还是更新
        if (order.getId() == null) {
            order.setCreateTime(new Date());
            parkingOrderMapper.insertParkingOrder(order);
        } else {
            order.setUpdateTime(new Date());
            parkingOrderMapper.updateParkingOrder(order);
        }

        PaymentDto paymentDto = new PaymentDto();
        paymentDto.setLy(paymentInsideDto.getLy());
        paymentDto.setOrderNo(order.getOrderNo());
        paymentDto.setUniqueId(paymentInsideDto.getUniqueId());
        paymentDto.setBody(order.getParkName()+"-"+order.getCarNum());
        paymentDto.setAmount(order.getActualAmount());
        return weChatService.weChatPay(paymentDto);
    }

    @Override
    @Transactional
    public Boolean paymentDiscount(PaymentDto paymentDto) {
        ParkingOrder parkingOrder = new ParkingOrder();
        parkingOrder.setOrderNo(paymentDto.getOrderNo());
        ParkingOrder order = parkingOrderMapper.selectParkingOrder(parkingOrder);
        Optional.ofNullable(order).orElseThrow(() -> new RuntimeException("暂未查询到缴费的订单"));
        Date date = new Date();
        order.setUniqueId(paymentDto.getUniqueId());
        order.setOrderStatus(3);
        order.setPayMethod(8);
        order.setPayAmount(BigDecimal.ZERO);
        order.setPayTime(LocalDateTime.now());
        order.setUpdateTime(date);
        parkingOrderMapper.updateParkingOrder(order);
        // 缴费成功状态通知设备
        chargeNotice(order);
        // 修改优惠券使用状态
        MerchantCouponIssue merchantCouponIssue = merchantCouponIssueMapper.selectMerchantCouponIssueById(order.getIssueId());
        Optional.ofNullable(merchantCouponIssue).orElseThrow(() -> new RuntimeException("支付失败"));
        merchantCouponIssue.setOrderNo(paymentDto.getOrderNo());
        merchantCouponIssue.setStatus(1);
        merchantCouponIssue.setUseTime(order.getCreateTime());
        merchantCouponIssueMapper.updateMerchantCouponIssue(merchantCouponIssue);
        // 多余的金额，返还给商户
        BigDecimal overpaidAmount = merchantCouponIssue.getFaceValue().subtract(order.getDiscountAmount());
        if(overpaidAmount.compareTo(BigDecimal.ZERO) > 0){
            merchantCouponOrderMapper.updateNotIssueAmountById(overpaidAmount, merchantCouponIssue.getOrderId());
        }
        // 增加优惠券使用记录
        MerchantUsageRecord merchantUsageRecord = new MerchantUsageRecord();
        merchantUsageRecord.setIssueId(order.getIssueId());
        merchantUsageRecord.setCouponCode(merchantCouponIssue.getCouponCode());
        merchantUsageRecord.setParkingRecordId(merchantCouponIssue.getParkingRecordId());
        merchantUsageRecord.setCarNum(order.getCarNum());
        merchantUsageRecord.setDiscountAmount(order.getDiscountAmount());
        merchantUsageRecord.setBeforeAmount(order.getTotalAmount().subtract(order.getActualAmount()));
        merchantUsageRecord.setAfterAmount(order.getActualAmount());
        merchantUsageRecord.setUseTime(order.getCreateTime());
        merchantUsageRecord.setCreateTime(date);
        merchantUsageRecordMapper.insertMerchantUsageRecord(merchantUsageRecord);
        return Boolean.TRUE;
    }

    @Override
    public Map<String, String> paymentParkCard(PaymentParkCardDto paymentParkCardDto) {
        int count = parkingCardMapper.selectParkingCardCount(paymentParkCardDto);
        if (count > 0) {
            throw new RuntimeException(paymentParkCardDto.getCarNum()+"已办理该车场停车卡");
        }
        // 创建支付信息
        PaymentDto paymentDto = new PaymentDto();
        paymentDto.setLy(paymentParkCardDto.getLy());
        paymentDto.setOrderNo(StringUtils.getOrderNo("CRD"));
        paymentDto.setUniqueId(paymentParkCardDto.getUniqueId());
        // 创建停车卡订单
        Long parkId = paymentParkCardDto.getParkId();
        String amount = parkingCardSpecMapper.selectAmountParkingCardSpec(parkId, paymentParkCardDto.getValid());
        ParkingInfo parkingInfo = parkingInfoMapper.selectParkingInfoById(paymentParkCardDto.getParkId());
        ParkingCardOrder cardOrder = AppMapper.INSTANCE.toParkingCardOrder(paymentParkCardDto);
        cardOrder.setOrderNo(paymentDto.getOrderNo());
        cardOrder.setOrderStatus(1);
        cardOrder.setValidStartTime(DateUtils.parseDate(paymentParkCardDto.getDate()));
        cardOrder.setValid(paymentParkCardDto.getValid());
        cardOrder.setPayAmount(new BigDecimal(amount));
        cardOrder.setDeptId(parkingInfo.getDeptId());
        cardOrder.setCreateTime(new Date());
        parkingCardOrderMapper.insertParkingCardOrder(cardOrder);
        paymentDto.setBody(parkingInfo.getParkName()+"-"+paymentParkCardDto.getCarNum());
        paymentDto.setAmount(cardOrder.getPayAmount());
        return weChatService.weChatPay(paymentDto);
    }

    @Override
    public ParkingInfo getParkingInfoByCode(String platformId, String parkCode) {
        ParkingInfo parkingInfo = parkingInfoMapper.selectParkingInfoByParkCode(platformId, parkCode);
        return parkingInfo;
    }

    /**
     * 获取场内停车费信息
     * @param scanInsideDto
     * @return
     */
    @Override
    public ScanInOutCodeVo scanOnSiteCode(ScanInsideDto scanInsideDto) {
        ParkingInfo parkingInfo = parkingInfoService.selectParkingInfoById(scanInsideDto.getParkId());
        if (parkingInfo == null){
            throw new RuntimeException("未查询到停车场信息");
        }
        ScanInOutCodeVo inParkingFeeInfo = getInParkingFeeInfo(parkingInfo, scanInsideDto.getCarNum());
        return inParkingFeeInfo;
    }

    @Override
    public List<Map<String, Object>> getParkingSelect() {
        return parkingInfoMapper.selectList();
    }

    @Override
    public String getParkCardAmount(Long parkId, Integer valid) {
        String amount = parkingCardSpecMapper.selectAmountParkingCardSpec(parkId, valid);
        return amount;
    }

    @Override
    public BigDecimal getParkingFee(Long couponId, String carNum) {
        ParkingInfo parkingInfo = parkingInfoMapper.selectParkingInfoByCouponId(couponId);
        if(Objects.isNull(parkingInfo)){
            throw new RuntimeException("未查询到停车场信息");
        }
        ScanOnSiteCodeRequest scanOnSiteCodeRequest = new ScanOnSiteCodeRequest();
        scanOnSiteCodeRequest.setCarNum(carNum);
        scanOnSiteCodeRequest.setParkingLotCode(parkingInfo.getParkCode());
        scanOnSiteCodeRequest.setPlatformId(parkingInfo.getPlatformId());
        ScanOnSiteCodeResponse scanOnSiteCodeResponse = parkingFeeQueryRequest(scanOnSiteCodeRequest);
        if(Objects.isNull(scanOnSiteCodeResponse)){
            throw new RuntimeException(carNum+"无在停记录");
        }
        BigDecimal fee = scanOnSiteCodeResponse.getConsumeMoney().subtract(scanOnSiteCodeResponse.getPayedMoney());
        return fee.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : fee;
    }

    /**
     * 缴费成功状态通知
     */
    private void chargeNotice(ParkingOrder order){
        String platformId = order.getPlatformId();
        // 组装请求参数
        ChargeNoticeRequest chargeNoticeRequest = new ChargeNoticeRequest();
        chargeNoticeRequest.setPlatformId(platformId);
        chargeNoticeRequest.setCarNum(order.getCarNum());
        chargeNoticeRequest.setCarNumColor(String.valueOf(order.getCarNumColor()));
        chargeNoticeRequest.setConsumeMoney(order.getTotalAmount());
        chargeNoticeRequest.setConsumeTimeStr(DateUtils.localDateTimeToStr(order.getPayTime()));
        chargeNoticeRequest.setFavorableAmount(order.getDiscountAmount());
        chargeNoticeRequest.setFeeAmount(order.getActualAmount());
        Integer payTypeSub = 0;
        int payMethod = order.getPayMethod().intValue();
        if(payMethod == 1){
            payTypeSub = DaHuaConfig.PAY_TYPE_WECHAT_H5;
        }else if(payMethod == 2){
            payTypeSub = DaHuaConfig.PAY_TYPE_WECHAT_XCX;
        }
        chargeNoticeRequest.setPayTypeSub(payTypeSub);
        chargeNoticeRequest.setOrderStatus(DaHuaConfig.PAY_SUCCESS);
        chargeNoticeRequest.setParkingLotCode(order.getParkCode());
        chargeNoticeRequest.setSerialNumber(order.getOrderNo());

        RequestData<ChargeNoticeRequest> requestData = new RequestData<>(
                MasWebsocketEnum.CHARGE_NOTIFY.getMethod(), chargeNoticeRequest);
        CommonRequest<ChargeNoticeRequest> noticeRequest = new CommonRequest<>("transform", 1, requestData);
        log.info("缴费成功通知请求JSON：{}", chargeNoticeRequest);
        try {
            Boolean result = webSocketMessageService.operationDevice(platformId, noticeRequest);
            log.info("缴费成功通知: {}", result);
        }catch (Exception e){
            e.printStackTrace();
            log.error("缴费通知失败：{}，下级平台：{}", e.getMessage(), platformId);
        }
    }

    /**
     * 停车费用查询
     */
    private ScanOnSiteCodeResponse parkingFeeQueryRequest(ScanOnSiteCodeRequest scanOnSiteCodeRequest){
        // 组装请求
        RequestData<ScanOnSiteCodeRequest> requestData = new RequestData<>(
                MasWebsocketEnum.PARKING_FEE_QUERY.getMethod(), scanOnSiteCodeRequest);
        CommonRequest<ScanOnSiteCodeRequest> scanRequest = new CommonRequest<>("transform", 1, requestData);
        log.info("停车费用查询请求JSON：{}", scanOnSiteCodeRequest.toString());
        // 查询停车信息
        String platformId = scanOnSiteCodeRequest.getPlatformId();
        ScanOnSiteCodeResponse scanOnSiteCodeResponse = null;
        try {
            scanOnSiteCodeResponse = webSocketMessageService.queryDevice(platformId, scanRequest, ScanOnSiteCodeResponse.class);
            log.info("停车费用查询信息: {}", scanOnSiteCodeResponse);
            return scanOnSiteCodeResponse;
        }catch (Exception e){
            e.printStackTrace();
            log.error("停车费用查询异常: {}", e.getMessage());
        }
        return scanOnSiteCodeResponse;
    }

    /**
     * 获取场内停车费用信息
     */
    private ScanInOutCodeVo getInParkingFeeInfo(ParkingInfo parkingInfo,String carNum){
        ScanOnSiteCodeRequest scanOnSiteCodeRequest = new ScanOnSiteCodeRequest();
        scanOnSiteCodeRequest.setPlatformId(parkingInfo.getPlatformId());
        scanOnSiteCodeRequest.setParkingLotCode(parkingInfo.getParkCode());
        scanOnSiteCodeRequest.setCarNum(carNum);
        // 组装请求
        RequestData<ScanOnSiteCodeRequest> requestData = new RequestData<>(
                MasWebsocketEnum.PARKING_FEE_QUERY.getMethod(), scanOnSiteCodeRequest);
        CommonRequest<ScanOnSiteCodeRequest> scanRequest = new CommonRequest<>("transform", 1, requestData);
        log.info("场内扫码请求JSON：{}", scanOnSiteCodeRequest.toString());
        // 查询停车信息
        String platformId = scanOnSiteCodeRequest.getPlatformId();
        try {
            ScanOnSiteCodeResponse scanOnSiteCodeResponse = webSocketMessageService.queryDevice(platformId, scanRequest, ScanOnSiteCodeResponse.class);
            log.info("场内扫码查询的停车信息: {}", scanOnSiteCodeResponse);
            ScanInOutCodeVo scanInOutCodeVo = new ScanInOutCodeVo();
            scanInOutCodeVo.setFirstTitle(parkingInfo.getFirstTitle());
            scanInOutCodeVo.setSecondTitle(parkingInfo.getSecondTitle());
            scanInOutCodeVo.setCarNum(scanOnSiteCodeResponse.getCarNum());
            scanInOutCodeVo.setParkName(parkingInfo.getParkName());
            LocalDateTime entryTime = DateUtils.strToLocalDateTime(scanOnSiteCodeResponse.getCarInTime());
            scanInOutCodeVo.setEntryTime(entryTime);
            scanInOutCodeVo.setFreeMinutes(scanOnSiteCodeResponse.getFeeOutTime().longValue());
            scanInOutCodeVo.setChargeMinutes(scanOnSiteCodeResponse.getParkTime().longValue());
            scanInOutCodeVo.setContactPhone(parkingInfo.getContactPhone());
            scanInOutCodeVo.setChargeDetail(parkingInfo.getChargeDetail());
            scanInOutCodeVo.setTotalAmount(scanOnSiteCodeResponse.getConsumeMoney());
            // 查询用户是否有优惠券
            MerchantCouponIssue couponIssue = merchantCouponIssueMapper.selectMerchantCouponIssueByCarNum(scanOnSiteCodeResponse.getCarNum(), parkingInfo.getId());
            // 需缴费总金额
            BigDecimal totalAmount = scanOnSiteCodeResponse.getConsumeMoney();
            if(Objects.nonNull(couponIssue)){
                // 优惠券金额
                BigDecimal discountAmount = couponIssue.getFaceValue();

                // 实际金额
                BigDecimal actualAmount = totalAmount.subtract(discountAmount);
                if (actualAmount.compareTo(BigDecimal.ZERO) >= 0){
                    scanInOutCodeVo.setDiscountAmount(discountAmount);
                    scanInOutCodeVo.setActualAmount(actualAmount);
                }else {
                    scanInOutCodeVo.setDiscountAmount(totalAmount);
                    scanInOutCodeVo.setActualAmount(BigDecimal.ZERO);
                }
            }else {
                scanInOutCodeVo.setDiscountAmount(BigDecimal.ZERO);
                scanInOutCodeVo.setActualAmount(totalAmount);
            }
            return scanInOutCodeVo;
        }
        catch (Exception e){
            e.printStackTrace();
            log.error("场内扫码查询异常: {}", e.getMessage());
        }
        return null;
    }
}
